/**
 * Copyright 2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.edi.client.param;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.edi.exceptions.EdiParamException;

/**
 * 记录并处理客户端传递的xml文件
 * 
 * 
 */
public class EdiClientRequest {
	private static final Log log = LogFactory.getLog(EdiClientRequest.class);
	private List<EdiClientParam> ediClientParams;
	private Document ediParaDoc;
	private String state;
	private StringBuffer errorInfo;
	private boolean isFileRequest;

	private Map<String, EdiTranPOClientParam> transactionMap;
	private List<EdiTranPOClientParam> transactionList;

	public EdiClientRequest(String ediPara) throws Exception {
		ediParaDoc = DocumentHelper.parseText(ediPara);
		Element root = ediParaDoc.getRootElement();
		isFileRequest = StringUtils.equalsIgnoreCase(root
				.elementText("isFileRequest"), "true");
		ediClientParams = new ArrayList<EdiClientParam>();
		errorInfo = new StringBuffer();
		transactionMap = new HashMap<String, EdiTranPOClientParam>();
		transactionList = new ArrayList<EdiTranPOClientParam>();
		state = "0";

		List<Element> paramsE = root.elements();
		/**
		 * 获取所有元素后，根据元素名，依照压入传递顺序，顺序保存，如果是非事务请求，则压入ediClientParams
		 * 如果是事务请求，则压入transactionList
		 */
		for (Element element : paramsE) {
			log.debug(" element.getName() " + element.getName());
			if (StringUtils.equalsIgnoreCase(element.getName(), "EPOParam")
					|| StringUtils.equalsIgnoreCase(element.getName(),
							"TPOParam")
					|| StringUtils.equalsIgnoreCase(element.getName(),
							"SPOParam")
					|| StringUtils.equalsIgnoreCase(element.getName(),
							"WAPParam")) {
				EdiClientParam ediClientParam;

				if (StringUtils.equalsIgnoreCase(element.getName(), "EPOParam"))
					ediClientParam = new EdiEPOClientParam(element);
				else if (StringUtils.equalsIgnoreCase(element.getName(),
						"TPOParam"))
					ediClientParam = new EdiTPOClientParam(element);
				else
					ediClientParam = new EdiSPOClientParam(element);

				log.debug(" ediClientParam =" + (ediClientParam.getClass()));
				String transactionName = ediClientParam.getTransaction();
				log.debug("transactionName =" + transactionName);
				if (StringUtils.isBlank(transactionName))
					ediClientParams.add(ediClientParam);
				else if ((ediClientParam instanceof EdiEPOClientParam)
						|| (ediClientParam instanceof EdiTPOClientParam)) {
					EdiTranPOClientParam tranParam = transactionMap
							.get(transactionName);
					if (tranParam == null) {
						tranParam = new EdiTranPOClientParam(ediClientParam
								.getDsName(), transactionName);
						transactionMap.put(transactionName, tranParam);
						transactionList.add(tranParam);
					}
					tranParam.addPoParam(ediClientParam);
				}
			}
		}

		//		Iterator<Element> ediEPOParams = root.elementIterator("EPOParam");
		//		Iterator<Element> ediTPOParams = root.elementIterator("TPOParam");
		//		Iterator<Element> ediSPOParams = root.elementIterator("SPOParam");
		//		Iterator<Element> ediWPOParams = root.elementIterator("WPOParam");

		//		while(ediEPOParams.hasNext()){
		//			Element ediParamElement = ediEPOParams.next();
		//			EdiClientParam ediClientParam = new EdiEPOClientParam(ediParamElement,appName,session);
		//			ediClientParams.add(ediClientParam);
		//		}
		//		
		//		while(ediTPOParams.hasNext()){
		//			Element ediParamElement = ediTPOParams.next();
		//			EdiClientParam ediClientParam = new EdiTPOClientParam(ediParamElement,appName,session);
		//			ediClientParams.add(ediClientParam);
		//		}
		//		
		//		while(ediSPOParams.hasNext()){
		//			Element ediParamElement = ediSPOParams.next();
		//			EdiClientParam ediClientParam = new EdiSPOClientParam(ediParamElement,appName,session);
		//			ediClientParams.add(ediClientParam);
		//		}
		//		while(ediWPOParams.hasNext()){
		//			Element ediParamElement = ediWPOParams.next();
		//			EdiClientParam ediClientParam;
		//			try {
		//				ediClientParam = new EdiWPOClientParam(ediParamElement,appName,session);
		//				ediClientParams.add(ediClientParam);
		//			} catch (WorkflowException e) {
		//				log.error(" EdiClientRequest error "+e.getMessage());
		//				e.printStackTrace();
		//			}

		//		}
	}

	/**
	 * 处理客户端请求
	 * 
	 * @throws EdiParamException
	 */
	public void process() {
		int paramSum = 0;
		//先执行事务，后执行其他动作
		log.debug(" before transactionList transactionList size"
				+ transactionList.size());
		for (EdiTranPOClientParam tranParam : transactionList) {
			try {
				tranParam.excuteClientParam();
				paramSum++;
			} catch (EdiParamException e) { //为保证一个请求错误不影响其他请求，在此做了容错处理 
				log.error("事务执行发生错误：");
				log.error(e.getMessage());
				errorInfo.append("事务执行发生错误：")
						.append(tranParam.getTransaction()).append("\n");
				//				errorInfo.append(e.getMessage()).append("\n");
				e.printStackTrace();
			}

		}
		log.debug(" after transactionList ediClientParams size"
				+ ediClientParams.size());

		for (EdiClientParam clientParam : ediClientParams) {
			try {
				clientParam.excuteClientParam();
				paramSum++;
			} catch (EdiParamException e) { //为保证一个请求错误不影响其他请求，在此做了容错处理 
				log.error("处理客户端请求时发生错误：");
				log.error(e.getMessage());
				errorInfo.append("处理客户端请求时发生错误：");
				errorInfo.append(e.getMessage()).append("\n");
				e.printStackTrace();
			}
		}

		if (paramSum == 0)
			state = "0";
		else
			state = "1";

	}

	public String getAnswerXml() {
		//		Document document = DocumentHelper.createDocument();
		//		document.setXMLEncoding("UTF-8");
		//		Element answer = document.addElement("ret");
		Element answer = DocumentHelper.createElement("ret");
		answer.addElement("state").setText(state);
		answer.addElement("errorInfo").addCDATA(errorInfo.toString());

		if (state.equals("0"))
			//			return document.asXML();
			return answer.asXML();
		else {
			for (EdiTranPOClientParam tranParam : transactionList) {
				answer.add(tranParam.answerClinentParam());
			}

			for (IClientParam clientParam : ediClientParams) {
				answer.add(clientParam.answerClinentParam());
			}
			//			return document.asXML();
			return answer.asXML();
		}
	}

	/**
	 * 获得执行结果，注意：非TableEntity，Element，和object2xml
	 * 
	 * @return
	 */
	public Object getSpoReuslt() {
		Object result = null;
		for (IClientParam clientParam : ediClientParams) {
			if (clientParam instanceof EdiSPOClientParam) {
				result = ((EdiSPOClientParam) clientParam).getResult()
						.getResult();
				break;
			}
		}
		return result;
	}

	public boolean isFileRequest() {
		return this.isFileRequest;
	}
}
